#include "VulkanApplication.h"
#include <vector>
#include <iostream>

int main(int argc, char** argv)
{
    VulkanApplication app("c05_renderloop", 1024, 768);
    if (!app.initialized())
    {
        printf("Failed to initialize VulkanApplication.\n");
        return 1;
    }

    // Create image views
    VkImageViewCreateInfo createInfo
    {
        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
        nullptr, 0,
        nullptr, VK_IMAGE_VIEW_TYPE_2D,
        app.getSurfaceFormat().format,
        { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
          VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
    };

    std::vector<VkImageView> swapchainImageViews(app.getSwapchainImages().size());
    for (size_t i = 0; i < swapchainImageViews.size(); ++i)
    {
        createInfo.image = app.getSwapchainImages()[i];
        VkResult result = vkCreateImageView(
            app.getDevice(), &createInfo, nullptr, &swapchainImageViews[i]);
        if (result != VK_SUCCESS)
        {
            printf("Failed to create image view: %zd.\n", i);
            return 1;
        }
    }

    // Main loop
    VkFence waitFence = nullptr;
    VkSemaphore semaphore = nullptr;

    VkFenceCreateInfo fenceInfo
    {
        VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
        nullptr, VK_FENCE_CREATE_SIGNALED_BIT
    };
    vkCreateFence(app.getDevice(), &fenceInfo, nullptr, &waitFence);

    VkSemaphoreCreateInfo semaphoreInfo
    {
        VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
        nullptr, 0
    };
    vkCreateSemaphore(app.getDevice(), &semaphoreInfo, nullptr, &semaphore);

    while (!app.shouldClose())
    {
        //vkWaitForFences(app.getDevice(), 1, &waitFence, VK_TRUE, UINT64_MAX);
        //vkResetFences(app.getDevice(), 1, &waitFence);

        uint32_t imageIndex = 0;
        VkResult result = vkAcquireNextImageKHR(app.getDevice(), app.getSwapchain(), UINT64_MAX,
                                                semaphore, VK_NULL_HANDLE, &imageIndex);
        switch (result)
        {
        case VK_SUCCESS:
            printf("Next image: %d\n", imageIndex); break;
        default:
            printf("Next image: %d (RESULT = %d)\n", imageIndex, result);
            app.setClosed(); break;
        }

        glfwPollEvents();
    }

    for (size_t i = 0; i < swapchainImageViews.size(); ++i)
        vkDestroyImageView(app.getDevice(), swapchainImageViews[i], nullptr);
    vkDestroySemaphore(app.getDevice(), semaphore, nullptr);
    vkDestroyFence(app.getDevice(), waitFence, nullptr);
    return 0;
}